package csvutil

import (
	"encoding/csv"
	"io"
	"os"

	"golang.org/x/text/encoding/simplifiedchinese"
	"golang.org/x/text/transform"
)

type csvOperator struct {
	readfile  *os.File
	writefile *os.File
	reader    *csv.Reader
	writer    *csv.Writer
}

func NewCsvOperator(csvfile string) (CsvOperator, error) {
	if err := ensureFileExists(csvfile); err != nil {
		return nil, err
	}

	// 读取文件内容检测编码
	data, err := os.ReadFile(csvfile)
	if err != nil {
		return nil, err
	}

	readFile, err := os.Open(csvfile)
	if err != nil {
		return nil, err
	}

	writeFile, err := os.OpenFile(csvfile, os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		readFile.Close()
		return nil, err
	}

	// 创建Reader时考虑编码
	var reader io.Reader = readFile
	if isGBK(data) {
		reader = transform.NewReader(readFile, simplifiedchinese.GBK.NewDecoder())
	}

	return &csvOperator{
		readfile:  readFile,
		writefile: writeFile,
		reader:    csv.NewReader(reader),
		writer:    csv.NewWriter(writeFile),
	}, nil
}

func (c *csvOperator) ReadAll() (records [][]string, err error) {
	return c.reader.ReadAll()
}

func (c *csvOperator) Write(rows []string) error {
	if err := c.writer.Write(rows); err != nil {
		return err
	}
	c.writer.Flush()
	return nil
}

func (c *csvOperator) Close() error {
	err1 := c.readfile.Close()
	err2 := c.writefile.Close()
	if err1 != nil {
		return err1
	}
	return err2
}

// 检查文件是否存在
func ensureFileExists(filePath string) error {
	_, err := os.Stat(filePath)
	if os.IsNotExist(err) {
		file, err := os.Create(filePath)
		if err != nil {
			return err
		}
		file.Close()
	}
	return nil
}

// 简单的GBK检测逻辑
func isGBK(data []byte) bool {
	length := len(data)
	var i int
	for i < length {
		if data[i] <= 0x7f {
			i++
			continue
		}
		if i+1 >= length {
			return false
		}
		if data[i] >= 0x81 && data[i] <= 0xfe &&
			data[i+1] >= 0x40 && data[i+1] <= 0xfe &&
			data[i+1] != 0x7f {
			i += 2
			continue
		}
		return false
	}
	return true
}
